package cn.stylefeng.guns.cloud.workflow.modular.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.cloud.workflow.modular.model.params.ApproveParam;
import cn.stylefeng.guns.cloud.workflow.modular.model.result.ApproveHistoryResult;
import cn.stylefeng.guns.cloud.workflow.modular.service.ActBaseService;
import cn.stylefeng.guns.cloud.workflow.modular.service.ApproveHistoryService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 审批记录 服务实现类
 *
 * @Author xuyuxiang
 * @Date 2019/11/14 18:08
 **/
@Service
public class ApproveHistoryServiceImpl implements ApproveHistoryService {

    private final String START_EVENT = "startEvent";

    private final String USER_TASK = "userTask";

    private final String APPROVE_HISTORY_LIST = "approveHistoryList";

    private final String APPROVE_OPERATE = "approveOperate";

    private final String ENTRUST_PREFIX = "【委托办理】";

    private final String START_TASK_NAME = "发起申请";

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ActBaseService actBaseService;

    /**
     * 获取审批记录列表
     *
     * @Author xuyuxiang
     * @Date 2019/11/1 16:37
     **/
    @Override
    public List<ApproveHistoryResult> getApproveHistoryResultList(String processInstanceId) {
        //获取历史参数记录
        List<HistoricVariableInstance> historicVariableInstanceList = historyService
                .createHistoricVariableInstanceQuery()
                .processInstanceId(processInstanceId)
                .list();
        List<ApproveHistoryResult> approveHistoryResultList = new ArrayList<>();
        for (HistoricVariableInstance historicVariableInstance : historicVariableInstanceList) {
            //获取参数名称
            String variableName = historicVariableInstance.getVariableName();
            //如果参数名称为审批记录名称，则取出
            if (APPROVE_HISTORY_LIST.equals(variableName)) {
                approveHistoryResultList = (List<ApproveHistoryResult>) historicVariableInstance.getValue();
            }
        }
        return approveHistoryResultList;
    }

    /**
     * 保存开始事件的审批意见（供流程开始后调用）
     *
     * @Author xuyuxiang
     * @Date 2019/11/4 14:17
     **/
    @Override
    public void saveStartEventApproveInfo(String processInstanceId) {

        //根据processInstanceId获取Task，此时Task一定处于运行中
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();

        //获取taskId
        String taskId = task.getId();
        //获取开始事件
        HistoricActivityInstance hisActivityInstanceStartEvent = this.getHisActivityInstanceStartEvent(processInstanceId);

        //获取历史流程实例
        HistoricProcessInstance historicProcessInstance = historyService
                .createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        //初始化审批意见参数集合
        List<ApproveHistoryResult> approveHistoryResultList = new ArrayList<>();

        //初始化ApproveHistoryResult
        ApproveHistoryResult approveHistoryResult = new ApproveHistoryResult();

        //获取启动用户
        String startUserId = historicProcessInstance.getStartUserId();

        String userName = actBaseService.getNameByUserId(startUserId);

        //操作为空
        int approveOperate = 0;

        String approveNote = "-";

        //审批人（发起人）姓名
        approveHistoryResult.setApproveUserName(userName);

        //任务名称
        approveHistoryResult.setTaskName(START_TASK_NAME);

        //获取任务创建时间
        Date startTime = hisActivityInstanceStartEvent.getStartTime();

        approveHistoryResult.setTaskCreateTime(DateUtil.formatDateTime(startTime));

        //获取任务结束时间（审批时间）
        Date endTime = hisActivityInstanceStartEvent.getEndTime();

        if (ObjectUtil.isNotEmpty(endTime)) {
            approveHistoryResult.setApproveTime(DateUtil.formatDateTime(endTime));
        } else {
            approveHistoryResult.setApproveTime("-");
        }

        //审批操作
        approveHistoryResult.setApproveOperate(approveOperate);

        //审批意见
        approveHistoryResult.setApproveNote(approveNote);

        approveHistoryResultList.add(approveHistoryResult);

        Map<String, Object> paramMap = new HashMap<>();

        //将审批意见作为参数存入
        paramMap.put(APPROVE_HISTORY_LIST, approveHistoryResultList);

        //设置参数
        taskService.setVariables(taskId, paramMap);
    }

    /**
     * 填充最新审批意见并返回
     *
     * @Author xuyuxiang
     * @Date 2019/11/4 16:16
     **/
    @Override
    public Map<String, Object> getLatestApproveInfo(ApproveParam approveParam) {

        String processInstanceId = approveParam.getProcessInstanceId();

        Integer approveOperate = approveParam.getApproveOperate();

        String approveNote = approveParam.getApproveNote();

        HistoricActivityInstance hisActivityInstanceUserTaskLatest = this
                .getHisActivityInstanceUserTaskLatest(processInstanceId);

        ApproveHistoryResult approveHistoryResult = new ApproveHistoryResult();

        //获取审批人姓名
        String assignee = hisActivityInstanceUserTaskLatest.getAssignee();

        String userName = actBaseService.getNameByUserId(assignee);

        String taskName = hisActivityInstanceUserTaskLatest.getActivityName();

        //审批人（发起人）姓名
        approveHistoryResult.setApproveUserName(userName);

        //任务名称，若该任务是委托办理的，则在taskName前加【委托办理】
        String taskId = hisActivityInstanceUserTaskLatest.getTaskId();
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
                .taskId(taskId)
                .singleResult();

        //如果当前任务节点owner不为空，且owner和assigne不一致，则标明当前记录为委托办理的
        String owner = historicTaskInstance.getOwner();

        String taskAssignee = historicTaskInstance.getAssignee();

        if (ObjectUtil.isNotEmpty(owner)) {

            if (!taskAssignee.equals(owner)) {
                approveHistoryResult.setTaskName(ENTRUST_PREFIX + taskName);
            } else {
                approveHistoryResult.setTaskName(taskName);
            }
        } else {
            approveHistoryResult.setTaskName(taskName);
        }

        //获取任务创建时间
        Date startTime = hisActivityInstanceUserTaskLatest.getStartTime();
        approveHistoryResult.setTaskCreateTime(DateUtil.formatDateTime(startTime));

        //获取任务结束时间（审批时间）
        Date endTime = hisActivityInstanceUserTaskLatest.getEndTime();
        if (ObjectUtil.isNotEmpty(endTime)) {
            approveHistoryResult.setApproveTime(DateUtil.formatDateTime(endTime));
        } else {
            String defineEndTime = DateUtil.now();
            approveHistoryResult.setApproveTime(defineEndTime);
        }

        //审批操作
        approveHistoryResult.setApproveOperate(approveOperate);

        //审批意见
        approveHistoryResult.setApproveNote(approveNote);

        //获取审批意见
        List<ApproveHistoryResult> approveHistoryList = this.getApproveHistoryResultList(processInstanceId);

        approveHistoryList.add(approveHistoryResult);

        //更新审批意见
        Map<String, Object> approveParamMap = new HashMap<>();
        approveParamMap.put(APPROVE_HISTORY_LIST, approveHistoryList);

        //将审批操作存入参数，以此控制条件流转
        approveParamMap.put(APPROVE_OPERATE, approveOperate);

        return approveParamMap;
    }

    /**
     * 获取流程实例中开始事件startEvent节点
     *
     * @Author xuyuxiang
     * @Date 2019/11/1 17:01
     **/
    private HistoricActivityInstance getHisActivityInstanceStartEvent(String processInstanceId) {
        return historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).activityType(START_EVENT).singleResult();
    }

    /**
     * 获取流程中最新审批UserTask节点，即最新一条
     *
     * @Author xuyuxiang
     * @Date 2019/11/4 11:28
     **/
    private HistoricActivityInstance getHisActivityInstanceUserTaskLatest(String processInstanceId) {
        return historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).activityType(USER_TASK)
                .orderByHistoricActivityInstanceStartTime().desc().list().get(0);
    }
}
